<?php

namespace App\Services;

use App\Models\Orders;
use App\Models\WxMinigameConfig;
use App\Models\WxMinigameKefu;
use App\Services\WechatApi\WechatApiMessage;

class WxMinigameMessageService extends ServiceBase
{
    // 组装校验微信消息推送的签名
    // https://developers.weixin.qq.com/miniprogram/dev/framework/server-ability/message-push.html
    public function checkMsgSign(array $params = [], string $token = ''): bool
    {
        $signature = $params["signature"];
        $timestamp = $params["timestamp"];
        $nonce     = $params["nonce"];
        $tmpArr    = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);
        return $tmpStr == $signature;
    }

    // 发送文本消息
    public function sendText(WxMinigameConfig $mini, $openid, $content)
    {
        $access_token = WechatService::getInstance()->getAccessToken($mini->appid, $mini->appsecret);
        WechatApiMessage::getInstance()->sendCustomMessageToText($access_token, $openid, $content);
    }

    // 发送图文链接消息
    public function sendLink(WxMinigameConfig $mini, $openid, $title, $description, $url, $thumb_url)
    {
        $access_token = WechatService::getInstance()->getAccessToken($mini->appid, $mini->appsecret);
        WechatApiMessage::getInstance()->sendCustomMessageToLink($access_token, $openid, $title, $description, $url, $thumb_url);
    }

    public function handleMsg(WxMinigameConfig $mini, $params)
    {
        $msg_type = $params['MsgType'] ?? '';

        // 根据不同消息类型进行处理
        switch ($msg_type) {
            // 文本消息
            case 'text':
                $this->msgTest($mini, $params);
                break;
            // 卡片消息
            case 'miniprogrampage':
                $this->msgProgrampage($mini, $params);
                break;
        }

        return true;
    }

    // 文本消息
    private function msgTest(WxMinigameConfig $mini, $params)
    {
        $openid = $params['FromUserName'];
        $msg = $params['Content'];

        // 精准匹配文本内容
        $kefu = WxMinigameKefu::where('appid', $mini->appid)->where('receive_type', WxMinigameKefu::RECEIVE_TYPE_TEXT)->where('receive_content', $msg)->first();
        if (!$kefu) {
            // 通用回复
            $kefu = WxMinigameKefu::where('appid', $mini->appid)->where('receive_type', WxMinigameKefu::RECEIVE_TYPE_TEXT)->where('receive_msg_type', 'common')->first();
        }
        if (!$kefu) {
            return;
        }

        // 推送消息
        $content = $kefu->reply_content;
        switch ($kefu->reply_msg_type) {
            case 'text':
                $this->sendText($mini, $openid, $content);
                break;
            case 'link':
                $content = fromXml("<xml>{$content}</xml>");
                if (is_array($content) && isset($content['Articles']['item'])) {
                    $data = $content['Articles']['item'];
                    $this->sendLink($mini, $openid, $data['Title'], $data['Description'], $data['Url'], $data['ThumbUrl']);
                }

                break;
        }

        return true;
    }

    // 小程序卡片消息
    private function msgProgrampage(WxMinigameConfig $mini, $params)
    {
        // PagePath 对应发送消息时的 sendMessagePath 字段
        $page_paths = explode(':', $params['PagePath'] ?? '');
        if (count($page_paths) != 2) {
            return;
        }

        $link_type = $page_paths[0];
        $kefu = WxMinigameKefu::where('appid', $mini->appid)->where('receive_type', WxMinigameKefu::RECEIVE_TYPE_LINK)->where('link', $link_type)->first();
        if (!$kefu) {
            return;
        }

        // 不同的卡片类型进行处理
        switch ($link_type) {
            // ios支付
            case 'order':
                $trade_no = $page_paths[1];
                $this->msgProgrampageOrder($mini, $kefu, $params, $trade_no);
                break;
        }
    }

    // ios支付
    private function msgProgrampageOrder(WxMinigameConfig $mini, WxMinigameKefu $kefu, $params, $trade_no)
    {
        $openid = $params['FromUserName'];
        $order = Orders::where('trade_no', $trade_no)->first();
        if (empty($order)) {
            return;
        }

        $url = config('app.url') . "/switch_pay/minigame?trade_no={$order->trade_no}";

        // 推送消息
        $content = $kefu->reply_content;
        switch ($kefu->reply_msg_type) {
            case 'text':
                $this->sendText($mini, $openid, $content);
                break;
            case 'link':
                $content = fromXml("<xml>{$content}</xml>");
                if (is_array($content) && isset($content['Articles']['item'])) {
                    $data = $content['Articles']['item'];
                    $this->sendLink($mini, $openid, $data['Title'], $data['Description'], $url, $data['ThumbUrl']);
                }

                break;
        }

        return true;
    }
}
